package ch.ethz.smseth;

import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import ch.ethz.smseth.ContactUtil.Contact;

public class Favorites
{
	public static final String DATABASE_NAME = "FavoritesDB";
	public static final int DATABASE_VERSION = 1;
	public static final String DATABASE_TABLE = "favorites";

	public static final String ID = "_id";
	public static final String NAME = "name";
	public static final String NUMBER = "number";
	public static final String TYPE = "type";
	public static final String LAST_USED = "last_used";

	public static final long TIME_UNTIL_DELETE = (long) (60 * 60 * 24 * 30 * 1.5);

	private static final String DATABASE_CREATE = "CREATE TABLE " + DATABASE_TABLE + " (" + ID + " INTEGER primary key, " + NAME + " TEXT not null, " + NUMBER + " TEXT not null, " + TYPE
			+ " TEXT, " + LAST_USED + " LONG not null);";

	private static Favorites _inst;
	private DBHelper _helper;
	private Context _ctx;

	public Favorites(Context ctx)
	{
		this._ctx = ctx;
		_helper = new DBHelper(_ctx, DATABASE_NAME, null, DATABASE_VERSION);
	}

	public static void initInstance(Context ctx)
	{
		if (_inst == null)
		{
			_inst = new Favorites(ctx);
		}
	}

	public static Favorites getInstance()
	{
		return _inst;
	}

	public SQLiteDatabase getReadableDatabase()
	{
		return _helper.getReadableDatabase();
	}

	public SQLiteDatabase getWriteableDatabase()
	{
		return _helper.getWritableDatabase();
	}

	public long insertFavorite(String number) throws SQLException
	{
		if (hasFavorite(number))
			return -1;

		Contact contact = ContactUtil.get(_ctx).fetchContactByNumber(number);
		if (contact != null)
		{
			ContentValues vals = new ContentValues();
			vals.put(NAME, contact.name);
			vals.put(NUMBER, number);
			vals.put(TYPE, contact.label);
			vals.put(LAST_USED, System.currentTimeMillis() / 1000);
			return getWriteableDatabase().insertOrThrow(DATABASE_TABLE, null, vals);
		}
		return -1;
	}

	public int removeFavorite(int id)
	{
		String rowFilter = ID + " = " + Integer.toString(id);
		return getWriteableDatabase().delete(DATABASE_TABLE, rowFilter, null);
	}

	private boolean hasFavorite(String number)
	{
		Cursor c = fetchFavorite(number);
		if (c.moveToFirst())
		{
			c.close();
			return true;
		}

		c.close();
		return false;
	}

	private Cursor fetchFavorite(String number)
	{
		return getReadableDatabase().query(DATABASE_TABLE, new String[] { ID, NAME, NUMBER, TYPE, LAST_USED }, NUMBER + " = '" + number + "'", null, null, null, null);
	}

	private Cursor fetchAll()
	{
		return getReadableDatabase().query(DATABASE_TABLE, new String[] { ID, NAME, NUMBER, TYPE, LAST_USED }, null, null, null, null, null);
	}

	public void cleanUpFavorites()
	{
		long lastUsed, now = System.currentTimeMillis() / 1000;
		Cursor c = fetchAll();
		while (c.moveToNext())
		{
			lastUsed = c.getLong(4);
			if (now - lastUsed > TIME_UNTIL_DELETE || !numberExists(c))
				removeFavorite(c.getInt(0));
		}
		c.close();
	}

	private boolean numberExists(Cursor favoriteCursor)
	{
		String name = favoriteCursor.getString(1);
		String number = favoriteCursor.getString(2);

		List<Contact> contacts = ContactUtil.get(_ctx).fetchContactsByName(name);

		for (Contact contact : contacts)
		{
			if (number.equals(contact.number))
			{
				return true;
			}
		}

		return false;
	}

	private class DBHelper extends SQLiteOpenHelper
	{

		public DBHelper(Context context, String name, CursorFactory factory, int version)
		{
			super(context, name, factory, version);
		}

		@Override
		public void onCreate(SQLiteDatabase db)
		{
			db.execSQL(DATABASE_CREATE);
		}

		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
		{
		}

	}
}
